package com.chuangfeng.building.common;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;

import com.chuangfeng.building.entity.TAdminInfo;
import com.chuangfeng.framework.core.common.config.Constants;
import com.chuangfeng.framework.core.common.struts2.ContextPvd;
import com.chuangfeng.framework.core.common.struts2.action.BaseAction;
import com.chuangfeng.framework.core.common.util.BeanUtils;
import com.chuangfeng.framework.core.common.util.GenericsUtils;
/**
 * 
 * 针对CNGI项目的核心ACTION，所有ACTION继承该类实现
 * @author xiedy
 *
 */
public class CoreAction<T extends Serializable, M extends CoreMng<T>> extends BaseAction implements InitializingBean{

	protected Class<T> entityClass; // Action所管理的Entity类型.

	protected Class idClass; // Action所管理的Entity的主键类型.

	protected String idName; // Action所管理的Entity的主键名.

	private M entityManager; // Action管理Entity所用的manager.
	
	/**
	 * LOG4J日志
	 */
	protected final Logger logger = Logger.getLogger(this.getClass());
	
	/**
	 * 取得entityClass的函数. JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。
	 */
	protected Class<T> getEntityClass() {
		return entityClass;
	}

	/**
	 * 获得EntityManager类进行CRUD操作,可以在子类重载.
	 */
	protected M getEntityManager() {
		Assert.notNull(entityManager, "Manager未能成功初始化");
		return entityManager;
	}

	/**
	 * Init回调函数,初始化一系列泛型参数.
	 */
	public void afterPropertiesSet() {
		// 根据T,反射获得entityClass
		entityClass = GenericsUtils.getSuperClassGenricType(getClass());

		// 根据M,反射获得符合M类型的manager
		List<Field> fields = BeanUtils.getFieldsByType(this, GenericsUtils.getSuperClassGenricType(getClass(), 1));
		Assert.isTrue(fields.size() == 1, "subclass's has not only one entity manager property.");
		try {
			entityManager = (M) BeanUtils.forceGetProperty(this, fields.get(0).getName());
			Assert.notNull(entityManager, "subclass not inject manager to action sucessful.");
		} catch (Exception e) {
			ReflectionUtils.handleReflectionException(e);
		}

		// 反射获得entity的主键类型
		try {
			idName = entityManager.getIdName();
			idClass = BeanUtils.getPropertyType(entityClass, idName);
		} catch (Exception e) {
			ReflectionUtils.handleReflectionException(e);
		}
	}

	@Autowired
	protected ContextPvd contextPvd;
}
